use crate::src::struct_and_type::{
    SortedArray, SortedArrayCompareFunc, SortedArrayEqualFunc, SortedArrayValue,
};

extern "C" {
    fn malloc(_: u64) -> *mut ();
    fn realloc(_: *mut (), _: u64) -> *mut ();
    fn free(_: *mut ());
    fn memmove(_: *mut (), _: *const (), _: u64) -> *mut ();
}
extern "C" fn sortedarray_first_index(
    mut sortedarray: *mut SortedArray,
    mut data: SortedArrayValue,
    mut left: u32,
    mut right: u32,
) -> u32 {
    let mut index: u32 = left;
    while left < right {
        index = left.wrapping_add(right).wrapping_div(2 as i32 as u32);
        let mut order: i32 = unsafe {
            ((*sortedarray).cmp_func).expect("non-null function pointer")(
                data,
                *((*sortedarray).data).offset(index as isize),
            )
        };
        if order > 0 {
            left = index.wrapping_add(1 as i32 as u32);
        } else {
            right = index;
        }
    }
    return index;
}
extern "C" fn sortedarray_last_index(
    mut sortedarray: *mut SortedArray,
    mut data: SortedArrayValue,
    mut left: u32,
    mut right: u32,
) -> u32 {
    let mut index: u32 = right;
    while left < right {
        index = left.wrapping_add(right).wrapping_div(2 as i32 as u32);
        let mut order: i32 = unsafe {
            ((*sortedarray).cmp_func).expect("non-null function pointer")(
                data,
                *((*sortedarray).data).offset(index as isize),
            )
        };
        if order <= 0 {
            left = index.wrapping_add(1 as i32 as u32);
        } else {
            right = index;
        }
    }
    return index;
}
#[no_mangle]
pub extern "C" fn sortedarray_get(
    mut array: *mut SortedArray,
    mut i: u32,
) -> *mut SortedArrayValue {
    if array.is_null() {
        return 0 as *mut SortedArrayValue;
    }
    return (unsafe { *((*array).data).offset(i as isize) }) as *mut SortedArrayValue;
}
#[no_mangle]
pub extern "C" fn sortedarray_length(mut array: *mut SortedArray) -> u32 {
    return unsafe { (*array).length };
}
#[no_mangle]
pub extern "C" fn sortedarray_new(
    mut length: u32,
    mut equ_func: SortedArrayEqualFunc,
    mut cmp_func: SortedArrayCompareFunc,
) -> *mut SortedArray {
    if equ_func.is_none() || cmp_func.is_none() {
        return 0 as *mut SortedArray;
    }
    if length == 0 as u32 {
        length = 16 as u32;
    }
    let mut array: *mut SortedArrayValue = (unsafe {
        malloc((::core::mem::size_of::<SortedArrayValue>() as u64).wrapping_mul(length as u64))
    }) as *mut SortedArrayValue;
    if array.is_null() {
        return 0 as *mut SortedArray;
    }
    let mut sortedarray: *mut SortedArray =
        (unsafe { malloc(::core::mem::size_of::<SortedArray>() as u64) }) as *mut SortedArray;
    if sortedarray.is_null() {
        (unsafe { free(array as *mut ()) });
        return 0 as *mut SortedArray;
    }
    (unsafe { (*sortedarray).data = array });
    (unsafe { (*sortedarray).length = 0 as u32 });
    (unsafe { (*sortedarray)._alloced = length });
    (unsafe { (*sortedarray).equ_func = equ_func });
    (unsafe { (*sortedarray).cmp_func = cmp_func });
    return sortedarray;
}
#[no_mangle]
pub extern "C" fn sortedarray_free(mut sortedarray: *mut SortedArray) {
    if !sortedarray.is_null() {
        (unsafe { free((*sortedarray).data as *mut ()) });
        (unsafe { free(sortedarray as *mut ()) });
    }
}
#[no_mangle]
pub extern "C" fn sortedarray_remove(mut sortedarray: *mut SortedArray, mut index: u32) {
    sortedarray_remove_range(sortedarray, index, 1 as u32);
}
#[no_mangle]
pub extern "C" fn sortedarray_remove_range(
    mut sortedarray: *mut SortedArray,
    mut index: u32,
    mut length: u32,
) {
    if index > (unsafe { (*sortedarray).length })
        || index.wrapping_add(length) > (unsafe { (*sortedarray).length })
    {
        return;
    }
    (unsafe {
        memmove(
            &mut *((*sortedarray).data).offset(index as isize) as *mut SortedArrayValue
                as *mut (),
            &mut *((*sortedarray).data).offset(index.wrapping_add(length) as isize)
                as *mut SortedArrayValue as *const (),
            (((*sortedarray).length).wrapping_sub(index.wrapping_add(length)) as u64)
                .wrapping_mul(::core::mem::size_of::<SortedArrayValue>() as u64),
        )
    });
    (unsafe { (*sortedarray).length = ((*sortedarray).length).wrapping_sub(length) });
}
#[no_mangle]
pub extern "C" fn sortedarray_insert(
    mut sortedarray: *mut SortedArray,
    mut data: SortedArrayValue,
) -> i32 {
    let mut left: u32 = 0 as u32;
    let mut right: u32 = unsafe { (*sortedarray).length };
    let mut index: u32 = 0 as u32;
    right = if right > 1 as u32 {
        right
    } else { 0 as u32
    };
    while left != right {
        index = left.wrapping_add(right).wrapping_div(2 as i32 as u32);
        let mut order: i32 = unsafe {
            ((*sortedarray).cmp_func).expect("non-null function pointer")(
                data,
                *((*sortedarray).data).offset(index as isize),
            )
        };
        if order < 0 {
            right = index;
        } else {
            if !(order > 0) {
                break;
            }
            left = index.wrapping_add(1 as i32 as u32);
        }
    }
    if (unsafe { (*sortedarray).length }) > 0 as u32
        && (unsafe {
            ((*sortedarray).cmp_func).expect("non-null function pointer")(
                data,
                *((*sortedarray).data).offset(index as isize),
            )
        }) > 0
    {
        index = index.wrapping_add(1);
        index;
    }
    if (unsafe { (*sortedarray).length }).wrapping_add(1 as i32 as u32)
        > (unsafe { (*sortedarray)._alloced })
    {
        let mut newsize: u32 = 0;
        let mut data_0: *mut SortedArrayValue = 0 as *mut SortedArrayValue;
        newsize = (unsafe { (*sortedarray)._alloced }).wrapping_mul(2 as i32 as u32);
        data_0 = (unsafe {
            realloc(
                (*sortedarray).data as *mut (),
                (::core::mem::size_of::<SortedArrayValue>() as u64).wrapping_mul(newsize as u64),
            )
        }) as *mut SortedArrayValue;
        if data_0.is_null() {
            return 0;
        } else {
            (unsafe { (*sortedarray).data = data_0 });
            (unsafe { (*sortedarray)._alloced = newsize });
        }
    }
    (unsafe {
        memmove(
            &mut *((*sortedarray).data).offset(index.wrapping_add(1 as i32 as u32) as isize)
                as *mut SortedArrayValue as *mut (),
            &mut *((*sortedarray).data).offset(index as isize) as *mut SortedArrayValue
                as *const (),
            (((*sortedarray).length).wrapping_sub(index) as u64)
                .wrapping_mul(::core::mem::size_of::<SortedArrayValue>() as u64),
        )
    });
    let fresh0 = unsafe { &mut (*((*sortedarray).data).offset(index as isize)) };
    *fresh0 = data;
    (unsafe { (*sortedarray).length = ((*sortedarray).length).wrapping_add(1) });
    (unsafe { (*sortedarray).length });
    return 1;
}
#[no_mangle]
pub extern "C" fn sortedarray_index_of(
    mut sortedarray: *mut SortedArray,
    mut data: SortedArrayValue,
) -> i32 {
    if sortedarray.is_null() {
        return -(1 as i32);
    }
    let mut left: u32 = 0 as u32;
    let mut right: u32 = unsafe { (*sortedarray).length };
    let mut index: u32 = 0 as u32;
    right = if right > 1 as u32 {
        right
    } else { 0 as u32
    };
    while left != right {
        index = left.wrapping_add(right).wrapping_div(2 as i32 as u32);
        let mut order: i32 = unsafe {
            ((*sortedarray).cmp_func).expect("non-null function pointer")(
                data,
                *((*sortedarray).data).offset(index as isize),
            )
        };
        if order < 0 {
            right = index;
        } else if order > 0 {
            left = index.wrapping_add(1 as i32 as u32);
        } else {
            left = sortedarray_first_index(sortedarray, data, left, index);
            right = sortedarray_last_index(sortedarray, data, index, right);
            index = left;
            while index <= right {
                if (unsafe {
                    ((*sortedarray).equ_func).expect("non-null function pointer")(
                        data,
                        *((*sortedarray).data).offset(index as isize),
                    )
                }) != 0
                {
                    return index as i32;
                }
                index = index.wrapping_add(1);
                index;
            }
            return -(1 as i32);
        }
    }
    return -(1 as i32);
}
#[no_mangle]
pub extern "C" fn sortedarray_clear(mut sortedarray: *mut SortedArray) {
    (unsafe { (*sortedarray).length = 0 as u32 });
}
